﻿#ifndef ARRAY_LIST_HPP
#define ARRAY_LIST_HPP
//
// Created by Administrator on 25-9-4.
//
// ReSharper disable CppParameterMayBeConst
#pragma once
#ifndef ARRAY_LIST_H
#define ARRAY_LIST_H
#include <stdexcept>
/// 模板类需要声明和定义放在一个头文件中编写 使用hpp文件格式说明 该类的声明和定义在一个文件中
#include "list.h"
template<typename E>
class array_list final : public list<E> {
    E* data_;
    int index_;
    int size_;
    int capacity_;
    void extension();
    void extension(int index);
public:
    array_list();
    ~array_list() override;
    void add(E* e) override;
    void add(E e) override;
    void add(E& e) override;
    void ist(int index, E* e) override;
    void ist(int index, E e) override;
    void ist(int index, E& e) override;
    void del(int index) override;
    E get(int index) override;
    E& get_r(int index) override;
    E* get_p(int index) override;
    int size() override;

    void sort(int (*compare) (E, E)) override;
    array_list& find(int (*cdt) (E, E)) override;
};

template<typename E>
void array_list<E>::extension() {
    if (this->size_ >= this->capacity_) {
        this->capacity_ *= 1.5;
        E* new_data = new E[this->capacity_];
        for (int i = 0; i < this->size_; i++) {
            new_data[i] = this->data_[i];
        }
        delete [] this->data_;
        this->data_ = new_data;
    }
}

template<typename E>
void array_list<E>::extension(int index) {
    if (index >= index_) {
        throw std::out_of_range("index out of range");
    }
    if (this->size_ >= this->capacity_) {
        this->capacity_ *= 1.5;
        E* new_data = new E[this->capacity_];
        for (int i = index; i <= this->index_; i++) {
            new_data[i + 1] = this->data_[i];
        }
        delete [] this->data_;
        this->data_ = new_data;
    }
}

template<typename E>
array_list<E>::array_list() {
    index_ = 0;
    size_ = 0;
    capacity_ = 10;
    data_ = new E[capacity_];
}

template<typename E>
array_list<E>::~array_list() {
    delete[] data_;
}

template<typename E>
void array_list<E>::add(E* e) {
    this->extension();
    this->data_[this->index_] = *e;
    ++this->index_;
    ++this->size_;
}
template<typename E>
void array_list<E>::add(E e) {
    this->extension();
    this->data_[this->index_] = e;
    ++this->index_;
    ++this->size_;
}
template<typename E>
void array_list<E>::add(E &e) {
    this->extension();
    this->data_[this->index_] = e;
    ++this->index_;
    ++this->size_;
}
template<typename E>
void array_list<E>::ist(int index, E* e) {
    this->extension(index);
    for (int i = index; i <= this->size_; i++) {
        this->data_[i + 1] = this->data_[i];
    }
    this->data_[index] = *e;
    ++this->index_;
    ++this->size_;
}
template<typename E>
void array_list<E>::ist(int index, E e) {
    this->extension(index);
    for (int i = index; i <= this->size_; i++) {
        this->data_[i + 1] = this->data_[i];
    }
    this->data_[index] = e;
    ++this->index_;
    ++this->size_;
}
template<typename E>
void array_list<E>::ist(int index, E &e) {
    this->extension(index);
    for (int i = index; i <= this->size_; i++) {
        this->data_[i + 1] = this->data_[i];
    }
    this->data_[index] = e;
    ++this->index_;
    ++this->size_;
}
template<typename E>
void array_list<E>::del(int index) {
    if (this->size_ == 0) {
        return;
    }
    if (index >= this->size_ || index < 0) {
        throw std::out_of_range("index out of range");
    }
    for (int i = index; i < this->size_; i++) {
        this->data_[i] = this->data_[i + 1];
    }
    --this->size_;
    --this->index_;
}

template<typename E>
E array_list<E>::get(int index) {
    if (index > this->size_) {
        throw std::out_of_range("index out of range");
    }
    return this->data_[index];
}

template<typename E>
E *array_list<E>::get_p(int index) {
    if (index > this->size_) {
        throw std::out_of_range("index out of range");
    }
    return &(this->data_[index]);
}

template<typename E>
E &array_list<E>::get_r(int index) {
    if (index > this->size_) {
        throw std::out_of_range("index out of range");
    }
    return *(&this->data_[index]);
}

template<typename E>
int array_list<E>::size() {
    return this->size_;
}

template<typename E>
void array_list<E>::sort(int (*compare)(E, E)) {
    //只使用快速排序的话在某些情况下速度可能会慢，
    //Timsort排序

}

template<typename E>
array_list<E> & array_list<E>::find(int (*cdt) (E, E)) {
    return *this;
}

#endif //ARRAY_LIST_H

#endif //ARRAY_LIST_HPP
